// static/main.js

// 维护一个“待上传”集合，包含 File 对象以及它的相对路径（相对于批次的顶层）
const queue = []; // { file: File, relPath: string }
const roots = new Set(); // 顶层根项（用于 commit 消息）

const dropzone = document.getElementById('dropzone');
const fileInput = document.getElementById('file-input');
const dirInput = document.getElementById('dir-input');
const preview = document.getElementById('preview');
const uploadBtn = document.getElementById('upload-btn');
const progressEl = document.getElementById('progress');
const resultEl = document.getElementById('result');

// 删除相关
function showDeleteConfirm(relPath, cb) {
    if (confirm(`确定要删除：${relPath}？`)) cb();
}

function setDeleteProgress(percent) {
    const p = Math.max(0, Math.min(100, percent | 0));
    progressEl.setAttribute('data-percent', p);
    const bar = progressEl.querySelector('.bar');
    if (bar) bar.style.width = p + '%';
}

async function deleteResource(relPath) {
    setDeleteProgress(5);
    resultEl.style.display = 'none';
    let progress = 0;
    let timer;
    function startPseudoProgress() {
        progress = 0;
        setDeleteProgress(progress);
        timer = setInterval(() => {
            if (progress < 70) {
                progress += 2;
            } else if (progress < 95) {
                progress += 0.2;
            } else {
                clearInterval(timer);
                return;
            }
            setDeleteProgress(progress);
        }, 100);
    }
    startPseudoProgress();
    try {
        const resp = await fetch('/delete', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ path: relPath }),
        });
        const data = await resp.json();
        clearInterval(timer);
        setDeleteProgress(100);
        if (!data.ok) {
            resultEl.className = 'ui negative message';
            resultEl.style.display = 'block';
            resultEl.textContent = `删除失败：${data.error || '未知错误'}`;
            return;
        }
        resultEl.className = 'ui positive message';
        resultEl.style.display = 'block';
        resultEl.textContent = '删除成功。';
        setTimeout(() => location.reload(), 600);
    } catch (e) {
        clearInterval(timer);
        resultEl.className = 'ui negative message';
        resultEl.style.display = 'block';
        resultEl.textContent = `网络或服务错误：${e}`;
    }
}

function updatePreview() {
    preview.innerHTML = '';
    queue.forEach(item => {
        const div = document.createElement('div');
        div.className = 'item';
        div.innerHTML = `
      <i class="file outline icon"></i>
      <div class="content mono">${item.relPath}</div>
    `;
        preview.appendChild(div);
    });
}

// 资源区删除按钮绑定（页面刷新后生效）
function bindDeleteButtons() {
    document.querySelectorAll('.resource-delete-btn').forEach(btn => {
        btn.addEventListener('click', function () {
            const rel = this.getAttribute('data-rel');
            showDeleteConfirm(rel, () => deleteResource(rel));
        });
    });
}

window.bindDeleteButtons = bindDeleteButtons;
document.addEventListener('DOMContentLoaded', bindDeleteButtons);

function addFileWithRelPath(file, relPath) {
    // 归一化路径展示
    const normalized = relPath.replace(/^\/+/, '');
    queue.push({ file, relPath: normalized });
    // 记录顶层根
    const top = normalized.split('/')[0];
    if (top) roots.add(top);
}

function traverseDataTransferItem(item, pathPrefix = '') {
    // 仅 chrome/edge 支持 webkitGetAsEntry
    const entry = item.webkitGetAsEntry ? item.webkitGetAsEntry() : null;
    if (!entry) return;

    if (entry.isFile) {
        entry.file(file => {
            addFileWithRelPath(file, pathPrefix + file.name);
            updatePreview();
        });
    } else if (entry.isDirectory) {
        const dirReader = entry.createReader();
        const readEntries = () => {
            dirReader.readEntries(entries => {
                if (!entries.length) return;
                entries.forEach(e => {
                    traverseDataTransferItem(
                        { webkitGetAsEntry: () => e },
                        pathPrefix + entry.name + '/'
                    );
                });
                readEntries();
            });
        };
        readEntries();
    }
}

dropzone.addEventListener('dragover', e => {
    e.preventDefault();
    dropzone.classList.add('dragover');
});
dropzone.addEventListener('dragleave', e => {
    dropzone.classList.remove('dragover');
});
dropzone.addEventListener('drop', e => {
    e.preventDefault();
    dropzone.classList.remove('dragover');

    const items = e.dataTransfer.items;
    if (items && items.length) {
        for (const it of items) {
            if (it.kind === 'file') {
                // 支持文件或文件夹（目录）
                if (it.webkitGetAsEntry) {
                    traverseDataTransferItem(it, '');
                } else {
                    // 回退：无法遍历目录时，只能当普通文件
                    const file = it.getAsFile();
                    if (file) addFileWithRelPath(file, file.name);
                }
            }
        }
        updatePreview();
    } else {
        // 回退：某些浏览器仅提供 files
        const files = e.dataTransfer.files;
        for (const f of files) {
            const rel = f.webkitRelativePath || f.name;
            addFileWithRelPath(f, rel);
        }
        updatePreview();
    }
});

fileInput.addEventListener('change', e => {
    const files = e.target.files;
    for (const f of files) {
        const rel = f.name; // 纯文件，顶层就是文件名
        addFileWithRelPath(f, rel);
    }
    updatePreview();
    fileInput.value = '';
});

dirInput.addEventListener('change', e => {
    const files = e.target.files;
    for (const f of files) {
        const rel = f.webkitRelativePath || f.name;
        addFileWithRelPath(f, rel);
    }
    updatePreview();
    dirInput.value = '';
});

function setProgress(percent) {
    const p = Math.max(0, Math.min(100, percent | 0));
    progressEl.setAttribute('data-percent', p);
    const bar = progressEl.querySelector('.bar');
    if (bar) bar.style.width = p + '%';
}

uploadBtn.addEventListener('click', async () => {
    if (queue.length === 0) {
        resultEl.className = 'ui warning message';
        resultEl.style.display = 'block';
        resultEl.textContent = '请先选择或拖拽文件/文件夹。';
        return;
    }

    const form = new FormData();
    queue.forEach(item => {
        form.append('files[]', item.file, item.file.name);
        form.append('paths[]', item.relPath);
    });
    // 记录本批次的顶层根项集合（用于分别 commit）
    Array.from(roots).forEach(r => form.append('batch_roots[]', r));

    setProgress(0);
    uploadBtn.classList.add('loading');
    resultEl.style.display = 'none';

    let progress = 0;
    let timer;

    function startPseudoProgress() {
        progress = 0;
        setProgress(progress);

        timer = setInterval(() => {
            if (progress < 70) {
                progress += 2; // 前期快
            } else if (progress < 95) {
                progress += 0.2; // 后期慢
            } else {
                // 到95%就停
                clearInterval(timer);
                return;
            }
            setProgress(progress);
        }, 100); // 每100ms更新一次
    }

    try {
        uploadBtn.classList.add('loading');
        startPseudoProgress();

        const resp = await fetch('/upload', {
            method: 'POST',
            body: form,
        });
        const data = await resp.json();

        clearInterval(timer);
        setProgress(100); // 请求完成，直接100%
        uploadBtn.classList.remove('loading');

        if (!data.ok) {
            resultEl.className = 'ui negative message';
            resultEl.style.display = 'block';
            resultEl.textContent = `上传失败：${data.error || '未知错误'}`;
            return;
        }

        resultEl.className = 'ui positive message';
        resultEl.style.display = 'block';
        resultEl.textContent = '上传并提交成功。';
        queue.length = 0;
        roots.clear();
        updatePreview();
        setTimeout(() => location.reload(), 600);
    } catch (e) {
        clearInterval(timer);
        uploadBtn.classList.remove('loading');
        resultEl.className = 'ui negative message';
        resultEl.style.display = 'block';
        resultEl.textContent = `网络或服务错误：${e}`;
    }
});
